from email import message
from fastapi import APIRouter, Depends
from constant.whiteList import get_white_list, put_white_list
from db.schemas import VersionCreate
from utils.utils import version2VersionVOList, int2version
from db.database import SessionLocal, get_db
from sqlalchemy.orm import Session
from domain.response import success, error
from domain.domain import UpdateVO, VersionVO
import service.whitelist as white

from typing import List, Optional
import db.version_config_crud as dbutils
from itertools import zip_longest
import json

router = APIRouter(
    prefix="/VersionConfig",
    tags=["VersionConfig"],
    dependencies=[],
    responses={404: {"description": "VersionConfig error"}}
)


def comparaversion(update_version_code, max_update_version_code):
    """
    判断版本号是否符合条件，先判断大版本，不符合返回-2，判断后续小版本，大于返回1，小于返回-1，等于返回0；
    """
    Bigu = update_version_code.split('.')[0]
    leftu = update_version_code.split('.')[1:]
    Bigm = max_update_version_code.split('.')[0]
    leftm = update_version_code.split('.')[1:]
    if int(Bigu) != int(Bigm):
        return -2
    for v1, v2 in zip_longest(leftu, leftm, fillvalue=0):
        x, y = int(v1), int(v2)
        if x != y:
            return 1 if x > y else -1
    return 0


@router.get("/getVersionByCondition")
async def get_version_by_condition(db: Session = Depends(get_db),
                                   platform: Optional[str] = None,  # 选择平台(android/ios)升级
                                   update_version_code: Optional[str] = None,  # 选择制定版本进行升级（有的话将最大版本号最小版本号同时设置为此值）
                                   max_update_version_code: Optional[str] = None,  # 选择可升级的最大版本号进行升级（默认所有中的最大值）
                                   min_update_version_code: Optional[str] = None,  # 选择可升级的最小版本号进行升级（默认所有中的最小值）
                                   max_os_api: Optional[int] = None,  # 选择支持的最大操作系统版本进行升级（默认所有中的最大值）
                                   min_os_api: Optional[int] = None,  # 选择支持的最小操作系统版本进行升级（默认所有中的最大值）
                                   cpu_arch: Optional[str] = None,  # 选择CPU架构进行升级
                                   channel: Optional[str] = None,
                                   page: Optional[int] = 1,  # 选择第几页
                                   page_number: Optional[int] = 10):  # 选择每页的版本信息数量
    if platform != 'Android' and platform != 'IOS' and platform is not None:
        return error(42004, "Platform is error !")
    if (update_version_code is not None
            and (comparaversion(update_version_code, max_update_version_code) in (1, 2, -1, -2))):
        return error(40003, "update_version_code is error !")
    if cpu_arch != 'x86' and cpu_arch != 'x64' and cpu_arch is not None:
        return error(42002, "Cpu_arch is error !")
    if channel != 'AppStore' and channel != 'GooglePlay' and channel is not None:
        return error(42001, "Channel is error !")
    version_do_list = await dbutils.get_version_by_condition(db, platform, update_version_code, max_update_version_code,
                                                             min_update_version_code, max_os_api, min_os_api, cpu_arch,
                                                             channel, page, page_number)
    version_do_count = await dbutils.get_version_count(db, platform, update_version_code, max_update_version_code,
                                                       min_update_version_code, max_os_api, min_os_api, cpu_arch,
                                                       channel, page, page_number)
    result = []
    for i in version_do_list:
        result.append(await version2VersionVOList(i))
    resp = {"list": result, "count": version_do_count}
    return await success(resp)


@router.post("/create_list")
async def create_list(version_bid: str, length: int):
    await white.create_list(version_bid, length)
    return await success(True)


@router.get("/id_in_whitelist")
async def id_in_whitelist(version: str, id: str):
    whitel = await get_white_list(version)
    if whitel is None or whitel.__len__ == 0:
        return await error(40014, "'please create whitelist first!'")
    if await white.id_in_whitelist(version, id):
        return await success(True)
    else:
        return await success(False)


@router.get("/open")
async def open_version(bid: str, msg: str, db: Session = Depends(get_db)):
    version = await dbutils.open_version(bid, msg, db)
    if version is None:
        return await error(code=41001, msg='This version has been deleted!')
    return await success(version)


@router.get("/close")
async def close_version(bid: str, msg: str, db: Session = Depends(get_db)):
    version = await dbutils.close_version(bid, msg, db)
    if version is None:
        return await error(code=41001, msg='This version has been deleted!')
    return await success(version)


@router.post("/delete")
async def delete_version(bid: str, msg: str, db: Session = Depends(get_db)):
    version = await dbutils.delete_version(bid, msg, db)
    if version is None:
        return await error(code=41001, msg='This version has been deleted!')
    return await success(version)


@router.post("/add")
async def add_version(ver: VersionCreate,
                      msg: str,
                      db: Session = Depends(get_db)):
    str_attrs = ['version', 'md5', 'download_url', 'cpu_arch', 'channel']
    int_attrs = ['max_os_api', 'min_os_api', 'max_version', 'min_version']
    for i in range(len(str_attrs)):
        if ver[str_attrs[i]] == '':
            return await error(code=41002 + i, msg="The %s can't be empty!" % str_attrs[i])

    for i in range(len(int_attrs)):
        if ver[int_attrs[i]] is None:
            return await error(code=41007 + i, msg="The %s can't be empty!" % int_attrs[i])

    version = await dbutils.add_version(ver, msg, db)
    return await success(version)


@router.post("/update")
async def update_version(ver: VersionCreate,
                         msg: str,
                         db: Session = Depends(get_db)):
    str_attrs = ['version', 'md5', 'download_url', 'cpu_arch', 'channel']
    int_attrs = ['max_os_api', 'min_os_api', 'max_version', 'min_version']
    for i in range(len(str_attrs)):
        if ver[str_attrs[i]] == '':
            return await error(code=41002 + i, msg="The %s can't be empty!" % str_attrs[i])

    for i in range(len(int_attrs)):
        if ver[int_attrs[i]] is None:
            return await error(code=41007 + i, msg="The %s can't be empty!" % int_attrs[i])

    version = await dbutils.update_version(ver, msg, db)
    if isinstance(version, dict):
        return await error(40015, "no version")
    return await success(version)
